package com.tanhua.server.interceptors;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.domain.db.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 统一token拦截器处理
 */
@Component
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 前置处理， 在进入controller方法前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //System.out.println("进入拦截器");
        //return true放行，可以访问controller方法
        //return false 拦截，不可以访问controller方法

        //记录请求的路径
        String requestMethod = request.getMethod();
        log.info("请求了路径: {}:{}",requestMethod, request.getRequestURI());

        //1. 校验token是否有效，无效就要返回401
        //1.1 从请求头中取出token,
        String token = request.getHeader("Authorization");
        // token可能没值，返回401
        if(StringUtils.isNotEmpty(token)) {
            //token有值
            User loginUser = getLoginUserByToken(token);
            //2. 校验通过后，把用户对象存入Threadlocal里
            //3. 把用户信息json字符串转成user对象,存入Threadlocal
            if(null != loginUser){
                UserHolder.setUser(loginUser);
                log.debug("当前登陆用户id为: {}", loginUser.getId());
                // 放行
                return true;
            }
        }
        // 401. Unauthorized，未认证，http状态码
        response.setStatus(401);
        return false;
    }

    /**
     * 通过token获取redis中存入的登录用户信息
     * @param token
     * @return
     */
    private User getLoginUserByToken(String token){
        //1.1 拼接key,必须与存入时的key要一致
        String key = "TOKEN_" + token;
        //1.2 从redis中取出
        String loginUserJsonString = stringRedisTemplate.opsForValue().get(key);
        //1.3 redis中没有值，重新登录
        if(StringUtils.isEmpty(loginUserJsonString)){
            // 返回空
            return null;
        }
        //1.4 有值，把json字符串转成java对象User
        return JSON.parseObject(loginUserJsonString, User.class);
    }
}
